﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using Core;
using IglooCoder.Commons.WcfNhibernate;
using Infrastucture;

namespace WcfService1
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "HppServices" in code, svc and config file together.
    public class HppServices : IHppServices
    {

        private readonly HppRepository hppRep;
        private readonly BtbElseRepository btbElseRepository;
        private readonly PurchaseInvoiceRepository purchaseInvoiceRepository;
        private readonly InventoryAdjustmentRepository inventoryAdjustmentRepository;
        private readonly SalesReturnRepository salesReturnRepository;
        private readonly SalesInvoiceRepository salesInvoiceRepository;
        private readonly InventoryRepository InventoryRep;
        private readonly MutasiStokRepository mutasiStokRep;

        public HppServices()
        {
            var sesssion = new WcfSessionStorage();
            hppRep = new HppRepository(sesssion);
            btbElseRepository = new BtbElseRepository(sesssion);
            purchaseInvoiceRepository = new PurchaseInvoiceRepository(sesssion);
            inventoryAdjustmentRepository = new InventoryAdjustmentRepository(sesssion);
            salesReturnRepository = new SalesReturnRepository(sesssion);
            salesInvoiceRepository = new SalesInvoiceRepository(sesssion);
            InventoryRep = new InventoryRepository(sesssion);
            mutasiStokRep = new MutasiStokRepository(sesssion);
        }
       
        public void CreateHpp(PurchaseInvoice purchaseInvoice)
        {
        

            foreach (var purchaseInvoiceDetail in purchaseInvoice.PurchaseInvoiceDetails)
            {
                var hpp = new Hpp();
                hpp.Tipe = typeof(PurchaseInvoice).ToString();
                hpp.ReffNumber = purchaseInvoice.PINo;

                var hppBefore = hppRep.FindLastHpp(purchaseInvoiceDetail.Inventory.SerialNumber, purchaseInvoice.PIDate);
                hpp.SerialNumber = purchaseInvoiceDetail.Inventory.SerialNumber;
                hpp.Tanggal = purchaseInvoice.PIDate;
                hpp.HppAwal = hppBefore.HppAkhir;
                hpp.QtyAwal = hppBefore.QtyAkhir;
                hpp.AmountAwal = hpp.HppAwal * hpp.QtyAwal;
                hpp.QtyIn = purchaseInvoiceDetail.Qty;
                hpp.HppIn = purchaseInvoiceDetail.Price;
                hpp.AmountIn = hpp.QtyIn * hpp.HppIn;
                hpp.QtyAkhir = hpp.QtyAwal + hpp.QtyIn - hpp.QtyOut;
                hpp.AmountAkhir = hpp.AmountAwal + hpp.AmountIn - hpp.AmountOut;
                hpp.HppAkhir = hpp.QtyAkhir != 0 ? hpp.AmountAkhir / hpp.QtyAkhir : 0;
                hppRep.SaveOrUpdate(hpp);
            }
        }

        public void CreateHpp(SalesInvoice salesInvoice)
        {

            foreach (var detail in salesInvoice.SalesInvoiceDetails)
            {
                var hpp = new Hpp();
                hpp.Tipe = typeof(SalesInvoice).ToString();
                hpp.ReffNumber = salesInvoice.SINo;

                var hppBefore = hppRep.FindLastHpp(detail.Inventory.SerialNumber, salesInvoice.InvoiceDate);
                if (hppBefore.HppAkhir == 0)throw new Exception(detail.Inventory.SerialNumber + " hpp sebelumnya tidak ada!");

                    hpp.SerialNumber = detail.Inventory.SerialNumber;
                    hpp.Tanggal = salesInvoice.InvoiceDate;
                    hpp.HppAwal = hppBefore.HppAkhir;
                    hpp.QtyAwal = hppBefore.QtyAkhir;
                    hpp.AmountAwal = hpp.HppAwal * hpp.QtyAwal;
                    hpp.QtyOut = detail.Qty;
                    hpp.HppOut = hpp.HppAwal;
                    hpp.AmountOut = hpp.QtyOut * hpp.HppOut;
                    hpp.QtyAkhir = hpp.QtyAwal + hpp.QtyIn - hpp.QtyOut;
                    hpp.AmountAkhir = hpp.AmountAwal + hpp.AmountIn - hpp.AmountOut;
                    hpp.HppAkhir = hpp.QtyAkhir != 0 ? hpp.AmountAkhir / hpp.QtyAkhir : 0;
                    hppRep.SaveOrUpdate(hpp);
            }
          
        }


        public void CreateHpp(PurchaseReturn purchaseReturn)
        {

            foreach (var detail in purchaseReturn.PurchaseReturnDetails)
            {
                var hpp = new Hpp();
                hpp.Tipe = typeof(PurchaseReturn).ToString();
                hpp.ReffNumber = purchaseReturn.PRNo;
                var hppBefore = hppRep.FindLastHpp(detail.Inventory.SerialNumber, purchaseReturn.PRDate);
                if (hppBefore.HppAkhir == 0) throw new Exception(detail.Inventory.SerialNumber + " hpp sebelumnya tidak ada!");

                hpp.SerialNumber = detail.Inventory.SerialNumber;
                hpp.Tanggal = purchaseReturn.PRDate;
                hpp.HppAwal = hppBefore.HppAkhir;
                hpp.QtyAwal = hppBefore.QtyAkhir;
                hpp.AmountAwal = hpp.HppAwal * hpp.QtyAwal;
                hpp.QtyOut = detail.Qty;
                hpp.HppOut = hpp.HppAwal;
                hpp.AmountOut = hpp.QtyOut * hpp.HppOut;
                hpp.QtyAkhir = hpp.QtyAwal + hpp.QtyIn - hpp.QtyOut;
                hpp.AmountAkhir = hpp.AmountAwal + hpp.AmountIn - hpp.AmountOut;
                hpp.HppAkhir = hpp.QtyAkhir != 0 ? hpp.AmountAkhir / hpp.QtyAkhir : 0;
                hppRep.SaveOrUpdate(hpp);
            }
        }

        public void CreateHpp(SalesReturn salesReturn)
        {

            foreach (var detail in salesReturn.SalesReturnDetails)
            {
                var hpp = new Hpp();
                hpp.Tipe = typeof(SalesReturn).ToString();
                hpp.ReffNumber = salesReturn.SRNo;
                var hppBefore = hppRep.FindLastHpp(detail.Inventory.SerialNumber, salesReturn.SRDate);
                hpp.SerialNumber = detail.Inventory.SerialNumber;
                hpp.Tanggal = salesReturn.SRDate;
                hpp.HppAwal = hppBefore.HppAkhir;
                hpp.QtyAwal = hppBefore.QtyAkhir;
                hpp.AmountAwal = hpp.HppAwal * hpp.QtyAwal;
                hpp.QtyIn = detail.QtyUnit;
                hpp.HppIn = detail.Price;
                hpp.AmountIn = hpp.QtyIn * hpp.HppIn;
                hpp.QtyAkhir = hpp.QtyAwal + hpp.QtyIn - hpp.QtyOut;
                hpp.AmountAkhir = hpp.AmountAwal + hpp.AmountIn - hpp.AmountOut;
                hpp.HppAkhir = hpp.QtyAkhir != 0 ? hpp.AmountAkhir / hpp.QtyAkhir : 0;
                hppRep.SaveOrUpdate(hpp);
            }
        }


        public void CreateHpp(BtbElse btbElse)
        {
           

            foreach (var detail in btbElse.BtbDetails)
            {
                var hpp = new Hpp();
                hpp.Tipe = typeof(BtbElse).ToString();
                hpp.ReffNumber = btbElse.NoBtb;
                var hppBefore = hppRep.FindLastHpp(detail.NoLog, btbElse.TglBtb);
                hpp.SerialNumber = detail.NoLog;
                hpp.Tanggal = btbElse.TglBtb;
                hpp.HppAwal = hppBefore.HppAkhir;
                hpp.QtyAwal = hppBefore.QtyAkhir;
                hpp.AmountAwal = hpp.HppAwal * hpp.QtyAwal;
                hpp.QtyIn = detail.QtyUnit;
                hpp.HppIn = detail.Price;
                hpp.AmountIn = hpp.QtyIn * hpp.HppIn;
                hpp.QtyAkhir = hpp.QtyAwal + hpp.QtyIn - hpp.QtyOut;
                hpp.AmountAkhir = hpp.AmountAwal + hpp.AmountIn - hpp.AmountOut;
                hpp.HppAkhir = hpp.QtyAkhir != 0 ? hpp.AmountAkhir / hpp.QtyAkhir : 0;
                hppRep.SaveOrUpdate(hpp);
            }
        }


        public void CreateHpp(InventoryAdjustment inventoryAdjustment)
        {
            if (inventoryAdjustment.Type.ToLower() == "in")
            {

                foreach (var detail in inventoryAdjustment.InventoryAdjustmentDetails)
                {
                    var hpp = new Hpp();
                    hpp.Tipe = typeof(InventoryAdjustment).ToString();
                    hpp.ReffNumber = inventoryAdjustment.NoAdj;

                    var hppBefore = hppRep.FindLastHpp(detail.Inventory.SerialNumber, inventoryAdjustment.TglAdjustment.Value);
                    hpp.SerialNumber = detail.Inventory.SerialNumber;
                    hpp.Tanggal = inventoryAdjustment.TglAdjustment;
                    hpp.HppAwal = hppBefore.HppAkhir;
                    hpp.QtyAwal = hppBefore.QtyAkhir;
                    hpp.AmountAwal = hpp.HppAwal * hpp.QtyAwal;
                    hpp.QtyIn = detail.QtyUnit;
                    hpp.HppIn = detail.Price;
                    hpp.AmountIn = hpp.QtyIn * hpp.HppIn;
                    hpp.QtyAkhir = hpp.QtyAwal + hpp.QtyIn - hpp.QtyOut;
                    hpp.AmountAkhir = hpp.AmountAwal + hpp.AmountIn - hpp.AmountOut;
                    hpp.HppAkhir = hpp.QtyAkhir != 0 ? hpp.AmountAkhir / hpp.QtyAkhir : 0;
                    hppRep.SaveOrUpdate(hpp);
                }
            }else
            {

                foreach (var detail in inventoryAdjustment.InventoryAdjustmentDetails)
                {
                    var hpp = new Hpp();
                    hpp.Tipe = typeof(InventoryAdjustment).ToString();
                    hpp.ReffNumber = inventoryAdjustment.NoAdj;

                    var hppBefore = hppRep.FindLastHpp(detail.Inventory.SerialNumber, inventoryAdjustment.TglAdjustment.Value);
                    if (hppBefore.HppAkhir == 0) throw new Exception(detail.Inventory.SerialNumber + " hpp sebelumnya tidak ada!");

                    hpp.SerialNumber = detail.Inventory.SerialNumber;
                    hpp.Tanggal = inventoryAdjustment.TglAdjustment;
                    hpp.HppAwal = hppBefore.HppAkhir;
                    hpp.QtyAwal = hppBefore.QtyAkhir;
                    hpp.AmountAwal = hpp.HppAwal * hpp.QtyAwal;
                    hpp.QtyOut = detail.QtyUnit;
                    hpp.HppOut = hpp.HppAwal;
                    hpp.AmountOut = hpp.QtyOut * hpp.HppOut;
                    hpp.QtyAkhir = hpp.QtyAwal + hpp.QtyIn - hpp.QtyOut;
                    hpp.AmountAkhir = hpp.AmountAwal + hpp.AmountIn - hpp.AmountOut;
                    hpp.HppAkhir = hpp.QtyAkhir != 0 ? hpp.AmountAkhir / hpp.QtyAkhir : 0;
                    hppRep.SaveOrUpdate(hpp);
                }
            }
        }

        public void CreateHpp(MutasiStok mutasiStok)
        {
            var hpp = new Hpp();
            hpp.Tipe = mutasiStok.Type;

            var hppBefore = hppRep.FindLastHpp(mutasiStok.SerialNumber, mutasiStok.TglMutasi);
            var inventory = InventoryRep.GetDataOne(x => x.SerialNumber == mutasiStok.SerialNumber);

            if (hppBefore.HppAkhir == 0 && mutasiStok.Type == "SaldoAwal")
            {
                hppBefore.HppAkhir = (decimal)inventory.UnitPrice;
                hppBefore.QtyAkhir = mutasiStokRep.GetQtyOnHand(mutasiStok.SerialNumber, mutasiStok.TglMutasi);
            }

            hpp.Tipe = mutasiStok.Type;
            hpp.ReffNumber = mutasiStok.ReferenceNumber;

            hpp.SerialNumber = mutasiStok.SerialNumber;
            hpp.Tanggal = mutasiStok.TglMutasi;
            hpp.HppAwal = hppBefore.HppAkhir;
            hpp.QtyAwal = hppBefore.QtyAkhir;
            hpp.AmountAwal = hpp.HppAwal * hpp.QtyAwal;

            if (mutasiStok.QtyMasuk > 0)
            {
                hpp.QtyIn = mutasiStok.QtyMasuk;
                if (mutasiStok.Type == "BtbElse")
                {
                    var btbElse = btbElseRepository.GetDataOne(x => x.NoBtb == mutasiStok.ReferenceNumber);
                    hpp.HppIn = btbElse.BtbDetails.FirstOrDefault(x => x.NoLog == mutasiStok.SerialNumber).Price;
                }
                else if (mutasiStok.Type == "BTB")
                {
                    var pi = purchaseInvoiceRepository.GetPurchaseInvoiceByBtb(mutasiStok.ReferenceNumber);
                    hpp.HppIn = pi.PurchaseInvoiceDetails.FirstOrDefault(x => x.Inventory.SerialNumber == mutasiStok.SerialNumber).Price;
                    hpp.ReffNumber = pi.PINo;
                }
                else if (mutasiStok.Type == "InventoryAdjustment")
                {
                    if (mutasiStok.QtyMasuk > 0)
                    {
                        var adj = inventoryAdjustmentRepository.GetDataOne(x => x.NoAdj == mutasiStok.ReferenceNumber);
                        hpp.HppIn = adj.InventoryAdjustmentDetails.FirstOrDefault(x => x.Inventory.SerialNumber == mutasiStok.SerialNumber).Price;
                    }

                }
                else if (mutasiStok.Type == "SalesReturn")
                {
                    var sr = salesReturnRepository.GetDataOne(x => x.SRNo == mutasiStok.ReferenceNumber);
                    hpp.HppIn = sr.SalesReturnDetails.FirstOrDefault(x => x.Inventory.SerialNumber == mutasiStok.SerialNumber).Price;
                }
                else
                {
                    hpp.HppIn = hppBefore.HppAkhir;
                }


                hpp.AmountIn = hpp.QtyIn * hpp.HppIn;
            }
            else
            {
                hpp.QtyOut = mutasiStok.QtyKeluar;
                hpp.HppOut = hpp.HppAwal;
                hpp.AmountOut = hpp.QtyOut * hpp.HppOut;
                if (mutasiStok.Type == typeof(DeliveryOrder).ToString())
                {
                    var si = salesInvoiceRepository.GetDataOne(x => x.DONo == mutasiStok.ReferenceNumber);
                    hpp.ReffNumber = si.SINo;
                }
            }

            hpp.QtyAkhir = hpp.QtyAwal + hpp.QtyIn - hpp.QtyOut;
            hpp.AmountAkhir = hpp.AmountAwal + hpp.AmountIn - hpp.AmountOut;
            hpp.HppAkhir = hpp.QtyAkhir != 0 ? hpp.AmountAkhir / hpp.QtyAkhir : 0;
            hppRep.SaveOrUpdate(hpp);
        }


        public void CreateHpp(DeliveryOrderElse deliveryOrderElse)
        {
         

            foreach (var detail in deliveryOrderElse.DeliveryOrderDetails)
            {
                var hpp = new Hpp();
                hpp.Tipe = typeof(SalesInvoice).ToString();
                hpp.ReffNumber = deliveryOrderElse.DONo;

                var hppBefore = hppRep.FindLastHpp(detail.Inventory.SerialNumber, deliveryOrderElse.DODate);
                if (hppBefore.HppAkhir == 0) throw new Exception(detail.Inventory.SerialNumber + " hpp sebelumnya tidak ada!");

                hpp.SerialNumber = detail.Inventory.SerialNumber;
                hpp.Tanggal = deliveryOrderElse.DODate;
                hpp.HppAwal = hppBefore.HppAkhir;
                hpp.QtyAwal = hppBefore.QtyAkhir;
                hpp.AmountAwal = hpp.HppAwal * hpp.QtyAwal;
                hpp.QtyOut = detail.QtyUnit;
                hpp.HppOut = hpp.HppAwal;
                hpp.AmountOut = hpp.QtyOut * hpp.HppOut;
                hpp.QtyAkhir = hpp.QtyAwal + hpp.QtyIn - hpp.QtyOut;
                hpp.AmountAkhir = hpp.AmountAwal + hpp.AmountIn - hpp.AmountOut;
                hpp.HppAkhir = hpp.QtyAkhir != 0 ? hpp.AmountAkhir / hpp.QtyAkhir : 0;
                hppRep.SaveOrUpdate(hpp);
            }

        }


    }
}
